/******************************************************************/
/*                                                                */
/*  Winpooch : Windows Watchdog                                   */
/*  Copyright (C) 2004  Benoit Blanchon                           */
/*                                                                */
/*  This program is free software; you can redistribute it        */
/*  and/or modify it under the terms of the GNU General Public    */
/*  License as published by the Free Software Foundation; either  */
/*  version 2 of the License, or (at your option) any later       */
/*  version.                                                      */
/*                                                                */
/*  This program is distributed in the hope that it will be       */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied    */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       */
/*  PURPOSE.  See the GNU General Public License for more         */
/*  details.                                                      */
/*                                                                */
/*  You should have received a copy of the GNU General Public     */
/*  License along with this program; if not, write to the Free    */
/*  Software Foundation, Inc.,                                    */
/*  675 Mass Ave, Cambridge, MA 02139, USA.                       */
/*                                                                */
/******************************************************************/

// module's interface
#include "Log.h"

// standards headers
#include <stdio.h>
#include <tchar.h>

// internal functions
VOID _Log_Append (LPCTSTR szText) ;

static HANDLE hLogFile ;
static CRITICAL_SECTION critsec ;
static TCHAR  szPath[MAX_PATH] ;

BOOL Log_Init (LPCTSTR szFile) 
{
  BOOL bAlreadyExists ;

  _tcscpy (szPath, szFile) ;

  hLogFile = CreateFile (szFile, GENERIC_WRITE,
			 FILE_SHARE_READ, NULL, 
			 OPEN_ALWAYS, 
			 FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,
			 NULL) ;
  
  if( hLogFile == INVALID_HANDLE_VALUE )
    return FALSE ;

  bAlreadyExists = GetLastError() == ERROR_ALREADY_EXISTS ;

  SetFilePointer (hLogFile, 0, NULL, FILE_END) ;

  if( bAlreadyExists )
    _Log_Append (TEXT("\r\n")) ;
  
  InitializeCriticalSection(&critsec) ;

  return TRUE ;
}

VOID Log_Uninit ()
{
  CloseHandle (hLogFile) ; 
  DeleteCriticalSection (&critsec) ;
}

VOID _Log_Append (LPCTSTR szText) 
{
  DWORD dwBytesWritten ;

  WriteFile (hLogFile,                // handle
	     szText,                  // buffer
	     lstrlen(szText)*sizeof(TCHAR), // size
	     &dwBytesWritten,          // bytes written
	     NULL) ;                  // overlapped
}

VOID Log_Print (LPCTSTR szText) 
{
  static DWORD dwTickPrevious ; 
  DWORD dwTickCurrent ;
  TCHAR szBuffer[32] ;
  DWORD dwSize ;

  EnterCriticalSection (&critsec) ;
   
  dwTickCurrent = GetTickCount() ;
  
  if( dwTickCurrent-dwTickPrevious > 2000 )
    {

      // get date string  
      GetDateFormat (LOCALE_USER_DEFAULT, // locale
		     DATE_LONGDATE,      // flags
		     NULL,                // date
		     NULL,                // format
		     szBuffer,            // string
		     sizeof(szBuffer)/sizeof(TCHAR)) ;  // buffer size
      
      // append date
      _Log_Append (szBuffer) ;
      
      // append separator
      _Log_Append (TEXT(" - ")) ;  
      
      // get time string
      GetTimeFormat (LOCALE_USER_DEFAULT, // locale
		     TIME_NOTIMEMARKER|   // flags
		     TIME_FORCE24HOURFORMAT,
		     NULL,                // time
		     NULL,                // format
		     szBuffer,            // string
		     sizeof(szBuffer)/sizeof(TCHAR)) ;  // buffer size
      
      // append time
      _Log_Append (szBuffer) ;
      
      // append separator
      _Log_Append (TEXT(" - ")) ; 
      
      // get the user name
      dwSize = sizeof(szBuffer)/sizeof(TCHAR) ;
      GetUserName (szBuffer, &dwSize) ;
      
      // append user name
      _Log_Append (szBuffer) ;
      
      // append newline and indent
      _Log_Append (TEXT("\r\n")) ;

    }

  // append indent
  _Log_Append (TEXT(" - ")) ;
      
  // append text
  _Log_Append (szText) ;

  // append newline
  _Log_Append (TEXT("\r\n")) ;

  dwTickPrevious = dwTickCurrent ;

  LeaveCriticalSection (&critsec) ;
}


VOID Log_Printf (LPCTSTR szFormat, ...)
{
  TCHAR szMessage[1024] ;
  va_list args ;
  
  va_start (args, szFormat) ;
  
  _vsntprintf (szMessage, 1024, szFormat, args) ;
  
  va_end (args) ;

  Log_Print (szMessage) ;
}

LPCTSTR Log_GetPath ()
{
  return szPath ;
}
